var Position = 0;
var itemsShown = 0;
var selectedTag = '';
var listStatus = 0;
var clickClosingFlag = 0;
var lastTagSubmitted = '';	//the last tag that was submited to server
var lastTag = '';		//the text that the user entered on the previous tagsGetter() iteration
var workingMode = 0;	//the tagsGetter func. uses it to know if it should get new items
var JSCache = [];
var position = 0; //used to determine where to place the tag when autocompleting
var totalLength = 0; //used to count the total chars passed to get to the current tag & determine where to position the select box
var registeredFields = [];
var lastListId = 'none'; //stores the last list id that the user was working on
var keyCode = 0;
var selectedField = 'none';
var curField = null; //store the current fieldItem for faster globall access
var registeredFieldsLog = []; //keep the IDs of all the fields that are currently registered.. used for a quick registration check

netscape = "";
ver = navigator.appVersion; len = ver.length;
for(iln = 0; iln < len; iln++) if (ver.charAt(iln) == "(") break;
netscape = (ver.charAt(iln+1).toUpperCase() != "C");

function keyDown(DnEvents) { // handles keypress
k = (netscape) ? DnEvents.which : window.event.keyCode;
keyCode = k;
return suggestEventHandler('test', keyCode);
}

document.onkeydown = keyDown; // work together to analyze keystrokes
document.onmousedown = mouseDown;
if (netscape) document.captureEvents(Event.KEYDOWN|Event.MouseDown);

function mouseDown(DnEvents) {
if (lastListId == 'none') return;
fieldItem = registeredFields[lastListId];
	if (fieldItem.listStatus == 1)
		setTimeout('hideList(fieldItem)', 250);
}


function switchPosition(moveWhere) {
	fieldItem = registeredFields[lastListId];
	xajax.$(fieldItem.container + 'Item' + fieldItem.position).className = 'xTabItem';
	fieldItem.position = moveWhere;
	if (moveWhere >= fieldItem.listItems) fieldItem.position = 0;
	else if (fieldItem.position < 0) fieldItem.position = fieldItem.listItems-1;
	xajax.$(fieldItem.container + 'Item' + fieldItem.position).className = 'xTabItemSelected';
}

function selectTag(fieldItem) {
addToLogger(fieldItem.fieldBox.value);
var tagsArray = fieldItem.fieldBox.value.split(",");
lastTagSubmitted = eval('fieldItem.item' + fieldItem.position);
tagsArray[fieldItem.tagPosition] = lastTagSubmitted;
for (i = 0; i < tagsArray.length; i = i+1)
	tagsArray[i] = trim(tagsArray[i]);
fieldItem.fieldBox.value = tagsArray.join(', ');
if (fieldItem.clickClosingFlag != 1) hideList(fieldItem);
fieldItem.fieldBox.focus();
}

function trim(str) {
   return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}

function hideList() {
	if (curField.listStatus == 0) return;	//dont close it if it's closed :D
	curField.position = 0;
	new Effect.Opacity(curField.container, {duration:0.2, from:1.0, to:0});
	fieldItem.listStatus = 0; //hidden
	if (curField.container != undefined)
		setTimeout("xajax.$('" + curField.container + "').style.visibility = 'hidden';", 200); //set it to invisible when the transition effect is over
	
	curField.closedOn = xajax.$(curField.fieldId).value;
	lastListId = 'none';
}

function showList() {
if (curField.html == '') return; //nothing to show
curField.fieldContainer.innerHTML = curField.html
	lastListId = curField.listId;
	curField.position = 0;	//reset the marker position
	
	curField.clickClosingFlag = 0;
	
	showAt = curField.totalLength*6;
	if (showAt > 400) showAt = 400;
	curField.fieldContainer.style.marginLeft = showAt+ 'px';
	addToLogger('positioned at: ' + showAt +'px');

	curField.fieldContainer.style.opacity = 0;
	curField.fieldContainer.style.visibility = 'visible';
	new Effect.Opacity(curField.container, {duration:0.2, from:0, to:1.0});
	curField.listStatus = 1; //indicates that the list is open
}

function getString() {
var myField = curField.fieldBox;
try {
	if (document.selection) { // IE support
		//addToLogger('IE sucks so for now you can only edit the last element of the array suckr');
		tagsArray = xajax.$(curField.fieldId).value.split(",");
		curField.totalLength = xajax.$(curField.fieldId).value.length;
		curField.tagPosition = tagsArray.length-1;
		//addToLogger('position is: ' + fieldItem.tagPosition);
		return tagsArray[tagsArray.length-1];
	}
	if (myField.selectionStart || myField.selectionStart == '0') { // MOZILLA/NETSCAPE support
		var startPos = myField.selectionStart;
		var endPos = myField.selectionEnd;
		tagsArray = xajax.$(curField.fieldId).value.split(",");
		returnA = 0;
		curField.totalLength = 0;
		for (i = 0; i < tagsArray.length; i++) {
		if (returnA != 0) continue;
		curField.totalLength = curField.totalLength + tagsArray[i].length + 2; //count the comma and space.too.. ;)
		if (curField.totalLength > startPos) {
		//if (tagsArray[i]!=fieldItem.lastTag) addToLogger('should be `' + tagsArray[i] + '`');
		curField.tagPosition = i;	//mark the place for the tag to be inserted
		returnA = tagsArray[i];
			}
		}
		//addToLogger(returnA);
		return returnA;
		addToLogger(myField.value.substring(0, startPos));
		myField.selectionStart = startPos + myValue.length;
		myField.selectionEnd = startPos + myValue.length;
	}
	
}
catch (e) { return ''; }
};

function addToLogger(text) {
return;
	xajax.$('logger').innerHTML += '<br>' + text;
}

function tagsGetter() {
if (selectedField == 'none') return;	//the selectedField var gets updated when a registered textbox gets clicked

curField = registeredFields[selectedField];

	if (curField.fieldBox.value.length == 0) {
		curField.lastTag = ''; curField.lastTagSubmitted = '';
		if (curField.listStatus == 1)	//we've got no text entered but the list is open.. close it!
			hideList();
		return;
	}
	text = getString();	//get the search string from the whole comma seperated list where the cursor is..

	if (text.length < 2 && curField.listStatus == 1) {	//close the list, less than 2 chars in current search string
		hideList();
		return;
	}

if (curField.lastTag == text && curField.lastTag != curField.lastTagSubmitted) {	//we've got an unchanged text that wasnt submitted
getTags(text);	//get new tags, whether from internal JS cache or from server
curField.lastTagSubmitted = text;
}
	curField.lastTag = text;	//set the current text as it's last change so that we have something to compare to later

}

function prepareContainer(containerId, fieldNum) {
	registeredFields[fieldNum].fieldContainer = xajax.$(containerId);
	registeredFields[fieldNum].fieldContainer.style.cursor = 'pointer';
	registeredFields[fieldNum].fieldContainer.style.position = 'absolute';
	registeredFields[fieldNum].fieldContainer.style.zIndex = '100';
}

function prepareBox(boxId, fieldNum) {
	registeredFields[fieldNum].fieldBox = xajax.$(boxId);
	registeredFields[fieldNum].fieldBox.autocomplete = 'off';
	registeredFields[fieldNum].fieldBox.onclick = function() { selectedField = fieldNum;}
}

function registerSuggestField(params) {
	if (params['fieldId'] == undefined)
		return throwCriticalError('Registering a field without a fieldId is not possible!');
	if (params['containerId'] == undefined)
		return throwCriticalError('Registering a field without a suggestions container is not possible!');
	if (params['response'] == undefined)
		return throwCriticalError('Registering a field without a xajax response function is not possible!');
		
	if (registeredFieldsLog[params['fieldId']] != undefined) {
		fieldNum = registeredFieldsLog[params['fieldId']];
		addToLogger('field is registered at ' + fieldNum +'! update only..');
		prepareContainer(params['containerId'], fieldNum);
		prepareBox(params['fieldId'], fieldNum);
		return;
	}

	var fieldNum = registeredFields.length;
	registeredFieldsLog[params['fieldId']] = fieldNum;

	registeredFields[fieldNum] =  {
	listId : fieldNum,
	listStatus: 0,
	position: 0,
	fieldId : params['fieldId'],
	container : params['containerId'],
	responseFunc : params['response'],
	suggestionsLimit : params['suggestionsLimit']};

	prepareContainer(params['containerId'], fieldNum);
	prepareBox(params['fieldId'], fieldNum);

	addToLogger(params['fieldId'] + ' initially registered at: ' + fieldNum);
}

xajax.command.handler.register('getList', function(args) {

	html = '';
	fieldItem = getFieldItem(args.fieldId);
	fieldItem.listItems = args.listItems;
	fieldItem.position = 0;

	for (i = 0; i < args.listItems; i++) {
	listItem = eval('args.data.listItem' + i);
		if (fieldItem.position == i)
			divClass='xTabItemSelected';
		else divClass='xTabItem';
		eval('fieldItem.item' + i + ' = \'' + listItem.value + '\'');
		width = 200;
html = html + '<div id="' + fieldItem.container + 'Item' +i + '" class="' + divClass + '" style="width:'+args.width+'px;" nowrap onmouseover="switchPosition('+i+');" onclick="selectTag(registeredFields['+fieldItem.listId+']);">' + listItem.display + '</div>';
		}
		
		fieldItem.html = html;
		
		/*
		storeVariable = fieldItem.fieldId + '_' + fieldItem.lastTagSubmitted;
		addToLogger('save to: ' + storeVariable);
		cacheItem = new CloneObject(fieldItem);
		JSCache[storeVariable] = cacheItem;
		*/
		selectedField = fieldItem.listId;
		curField = fieldItem;
		showList();
});
	
	

function CloneObject(inObj)
{
    for (i in inObj)
    {
        this[i] = inObj[i];
    }
}

function getFieldItem(fieldId) {
	returnF = 0;
	for (i = 0; i < registeredFields.length; i++)
		{
		if (returnF != 0) continue;
		if (registeredFields[i].fieldId == fieldId) returnF = registeredFields[i];
		}
	returnF = returnF;
	return returnF;
}
	
function getTags(text) {
	curField.lastTagSubmitted = text;
	
	/*
	storeVariable = curField.fieldId + '_' + text;
	addToLogger('store variable is: ' + storeVariable);
	if (JSCache[storeVariable] != undefined) {
		addToLogger('used cached content for ' + text);
		fieldItem = JSCache[storeVariable];
		registeredFields[0] = JSCache[storeVariable];
		fieldItem.lastTagSubmitted = text;
		showList();
	}
	else */{
	if (curField.fieldBox.value == curField.closedOn) {
	/*addToLogger('just closed :)');*/
	return;
	}

	eval(curField.responseFunc)(curField.fieldId, text, curField.suggestionsLimit);
	addToLogger('should have requested tags for ' + text);
	}
}

function suggestEventHandler(value, keyCode) {
if (lastListId != 'none') {
if (keyCode == 9) {selectTag(registeredFields[lastListId]); return false;}
if (keyCode == 38) {switchPosition(registeredFields[lastListId].position-1); return false;}
if (keyCode == 40) {switchPosition(registeredFields[lastListId].position+1); return false;}
if (keyCode == 27) {hideList(registeredFields[lastListId]); return false;}
}
return true;
}

function throwCriticalError(errorMsg) {
	alert(errorMsg);
	return false;
}

setInterval('tagsGetter()', 200);